﻿using System;
using System.Collections.Generic;
using System.Dynamic;
using System.Linq;
using System.Web.Mvc;
using NetSurveillance.WebApp.DataServices.Models;
using NetSurveillance.WebApp.Utilities;

namespace NetSurveillance.WebApp.Controllers
{
    public class MockDataController : BaseController
    {
        protected override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            base.OnActionExecuting(filterContext);
            if (CurrentTask == null)
            {
                filterContext.Result = Content("None Task is running.");
            }
        }
        public ActionResult CreateHost(int count = 50)
        {
            for (int i = 0; i < count; i++)
            {
                string hostIp = CreateRandomHostIp();
                string mac = CreateRandomMac();
                var host = new Host
                    {
                        HostName = string.Format("{0}/{1}", mac, hostIp),
                        IP = hostIp,
                        Mac = mac,
                        TaskId = CurrentTask.Id
                    };
                if (!DataProvider.HostService.GetAllModels(false, p => p.IP == hostIp && p.Mac == mac).Any())
                    DataProvider.HostService.Save(host);
            }
            return Content("Create Host Success");
        }

        public ActionResult CreateDataRecords(int count = 100)
        {
            long tick = DateTime.Now.Ticks;
            var random = new Random((int)(tick & 0xffffffffL) | (int)(tick >> 32));
            var hosts = DataProvider.HostService.GetAllModels();
            long maxHostId = hosts.Max(p => p.Id);
            IList<DataRecord> saveDataRecords = new List<DataRecord>();
            var protocols = SupportUtility.GetSupportProtocols().ToArray();
            var groups = DataProvider.DataIMRecordService.GetGroups(CurrentTask.Id).ToList();
            var nativeQQs = DataProvider.DataIMRecordService.GetLocalIMs(CurrentTask.Id).ToList();
            var remoteQQs = DataProvider.DataIMRecordService.GetRemoteIMs(CurrentTask.Id).ToList();
            for (int i = 0; i < count; i++)
            {
                long hostId = random.Next(1, (int) maxHostId);
                long? accountId = GetRandomAccountId();
                string dataRecordType = random.Next()%2 == 0 ? "down" : "up";
                bool isHaveTitle = random.Next(10)%4 != 0;
                string protocol = protocols[random.Next(protocols.Length)].Name;
                protocol = protocol == "http" && random.Next(10)%2 == 0 ? "webpost" : protocol;
                bool isGenerateEmail = "smtp,pop3".Contains(protocol.ToLower());
                long? dataIMRecordId = null;
                if (protocol.ToLower() == "qq")
                {
                    dataIMRecordId = CreateDataIMRecord(CurrentTask.Id, hostId, protocol, ref groups,
                                                        ref nativeQQs, ref remoteQQs);
                }
                var dataRecord = new DataRecord
                    {
                        HostId = hostId, 
                        TaskId = CurrentTask.Id,
                        SensitiveAccountId = accountId == 0 ? null : accountId,
                        DataIMRecordId = dataIMRecordId,
                        Title = isHaveTitle ? CreateRandomString(10) : null,
                        Protocol = protocol,
                        DataRecordType = dataRecordType,
                        RemoteIP = CreateRandomHostIp(),
                        RemoteMac = CreateRandomMac(),
                        MailCC = isGenerateEmail ? CreateRandomEmail() : null,
                        MailFrom = isGenerateEmail ? CreateRandomEmail() : null,
                        MailTo = isGenerateEmail ? CreateRandomEmail() : null
                    };
                saveDataRecords.Add(dataRecord);
            }
            DataProvider.DataRecordService.SaveAll(saveDataRecords);
            var dataRecords = DataProvider.DataRecordService.GetAllModels(false, p => p.TaskId == CurrentTask.Id);
            var keywords = DataProvider.KeywordService.GetAllModels(false, p => p.TaskId == CurrentTask.Id);
            if (dataRecords != null && keywords != null && dataRecords.Any() && keywords.Any())
            {
                var saveDataKeywords = new List<DataRecordKeyword>();
                var keywordArr = keywords.ToArray();
                var dataRecordArr = dataRecords.ToArray();
                for (int i = 0; i < count / 5; i++)
                {
                    long keywordId = keywordArr[random.Next(keywordArr.Length - 1)].Id;
                    long dataRecordId = dataRecordArr[random.Next(dataRecordArr.Length - 1)].Id;
                    if (DataProvider.DataRecordService.GetDataRecordKeyword(dataRecordId, keywordId) != null) 
                        continue;
                    var dataKeyword = new DataRecordKeyword
                    {
                        KeywordId = keywordId,
                        DataRecordId = dataRecordId
                    };
                    saveDataKeywords.Add(dataKeyword);
                }
                DataProvider.DataRecordService.SaveDataRecordKeywords(saveDataKeywords);
            }
            
            return Content("Create Data Records Success");
        }

        private long CreateDataIMRecord(long taskId, long hostId, string protocol,
                                        ref List<IMRecordGroup> groups, ref List<DataIMRecordResult> localQQs,
                                        ref List<DataIMRecordResult> remoteQQs)
        {
            long tick = DateTime.Now.Ticks;
            var random = new Random((int) (tick & 0xffffffffL) | (int) (tick >> 32));
            string groupNumber;
            string nativeQQNumber,
                   remoteQQNumber;
            if ((!groups.Any() || !localQQs.Any() || !remoteQQs.Any()) ||
                (random.Next(10)%3) != 0)
            {
                nativeQQNumber = CreateRandomQQ(random);
                if (localQQs.All(p => p.LocalNumber != nativeQQNumber))
                    localQQs.Add(new DataIMRecordResult {LocalNumber = nativeQQNumber});
                remoteQQNumber = CreateRandomQQ(random);
                if (remoteQQs.All(p => p.RemoteNumber != remoteQQNumber))
                    remoteQQs.Add(new DataIMRecordResult {RemoteNumber = remoteQQNumber});
                groupNumber = CreateRandomQQ(random);
                if (groups.All(p => p.GroupNumber != groupNumber))
                {
                    groups.Add(new IMRecordGroup {GroupNumber = groupNumber});
                }
            }
            else
            {
                int nativeCount = (localQQs.Count - 1) < 0 ? 0 : (localQQs.Count - 1),
                    remoteCount = (remoteQQs.Count - 1) < 0 ? 0 : (remoteQQs.Count - 1),
                    groupCount = (groups.Count - 1) < 0 ? 0 : (groups.Count - 1);
                nativeQQNumber = localQQs.ToArray()[random.Next(nativeCount)].LocalNumber;
                remoteQQNumber = remoteQQs.ToArray()[random.Next(remoteCount)].RemoteNumber;
                var group = groups.ToArray()[random.Next(groupCount)];
                groupNumber = group.GroupNumber;
            }
            bool isSend = random.Next(10)%2 == 0;
            bool isGroup = random.Next(16)%4 == 0;
            var dataIMRecord =
                new DataIMRecord
                    {
                        TaskId = taskId,
                        HostId = hostId,
                        LocalNumber = nativeQQNumber,
                        RemoteNumber = remoteQQNumber,
                        Content = "测试聊天内容" + random.Next(100),
                        GroupNumber = isGroup ? groupNumber : null,
                        Protocol = protocol,
                        Direction = isSend ? "send" : "recv"
                    };
            DataProvider.DataIMRecordService.Save(dataIMRecord);
            return dataIMRecord.Id;
        }

        private long GetRandomAccountId()
        {
            long tick = DateTime.Now.Ticks;
            var random = new Random((int)(tick & 0xffffffffL) | (int)(tick >> 32));
            long accountId = 0;
            if (random.Next(10) % 3 == 0)
            {
                var account = CreateAccount();
                accountId = account.Id;
            }
            else if (random.Next(10) % 3 == 1)
            {
                var allAccount = 
                    DataProvider.SensitiveAccountService.GetAllModels(false, p => p.TaskId == CurrentTask.Id).ToArray();
                if (allAccount.Any())
                    accountId = allAccount[random.Next(allAccount.Length - 1)].Id;
            }
            return accountId;
        }

        private SensitiveAccount CreateAccount()
        {
            var sensitiveAccount = new SensitiveAccount();
            long tick = DateTime.Now.Ticks;
            var random = new Random((int)(tick & 0xffffffffL) | (int)(tick >> 32));
            string account = CreateRandomString(random.Next(3, 10));
            string pass = CreateRandomString(random.Next(6, 20));
            sensitiveAccount.Account = account;
            sensitiveAccount.Password = pass;
            sensitiveAccount.TaskId = CurrentTask.Id;
            DataProvider.SensitiveAccountService.Save(sensitiveAccount);

            return sensitiveAccount;
        }

        private string CreateRandomMac()
        {
            string[] macArr = new string[6];
            for (int i = 0; i < 6; i++)
            {
                macArr[i] = CreateRandomString(2);
            }
            return string.Format("{0}-{1}-{2}-{3}-{4}-{5}", macArr);
        }

        private string CreateRandomHostIp()
        {
            long tick = DateTime.Now.Ticks;
            Random random = new Random((int)(tick & 0xffffffffL) | (int) (tick >> 32));
            int randomValue = random.Next(1, 255);
            return string.Format("192.168.1.{0}", randomValue);
        }

        private string CreateRandomEmail()
        {
            string codeStr = CreateRandomString(3);
            return string.Format("{0}@{0}.com", codeStr);
        }

        private string CreateRandomString(int count = 1)
        {
            string codeStr = string.Empty;
            string guidStr = Guid.NewGuid().ToString().Replace("-", "");
            if (count < 32)
                codeStr = guidStr.Substring(0, count);
            else
                codeStr = guidStr.Substring(0, 32) + CreateRandomString(count - 32);
            return codeStr;
        }

        private string CreateRandomQQ(Random random)
        {
            string qq = string.Empty;
            int qqLen = random.Next(6, 11);
            for (int i = 0; i < qqLen; i++)
            {
                qq += random.Next(9);
            }
            return qq;
        }
    }
}
